/**
 * Object.create, Courtesy of Papa Crockford
 */
if(typeof Object.create !== 'function')
{
    Object.create = function(o)
    {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

(function($) {

    //$.plugin, http://alexsexton.com/?p=51
    $.plugin = function(name, object)
    {
        $.fn[name] = function(options)
        {
            return this.each(function()
            {
                if (!$.data(this, name))
                {
                    $.data(this, name, Object.create(object).init(options, this));
                }
            });
        };
    };

/* Main Plugin
/---------------------------------------------------------------------------------------------------------------------*/
    //elem, $elem, options
    var pimFormBuild =
    {
        options:
        {
            onvalid  : function() {},
            onerror  : function() {},
            callback : function() {},
            onsubmit : function() {},
            url      : null,
            format   : 'json',
            data     : {}
        },
        init : function(options, elem)
        {
            // Mix in the passed in options with the default options
            this.options = $.extend({}, this.options, options);

            //pure js element
            this.elem = elem;

            //jquery element
            this.$elem = $(elem);

            //If a url is not been provided then look for the form action attr value
            if(this.options.url == null) this.options.url = this.$elem.attr('action');

            //bind the submit event
            this.unbind();
            this.bind();

            return this;
        },
        bind: function()
        {
            //bind the element
            this.$elem.bind('submit.pimForm', $.proxy(this.submit, this));
        },
        unbind: function()
        {
            this.$elem.unbind('submit.pimForm');
        },
        clearFields: function()
        {
            //Remove all the ul list
            this.$elem.find('ul.errors').empty();
            this.$elem.find('input, textarea, select').removeClass('error');
        },
        submit: function(event)
        {
            var $el  = $(event.target);
            var obj  = this;
            var $input, messages, $ul;

            //Reset the form to it's original state
            obj.clearFields();

            //Trigger onsubmit event
            obj.options.onsubmit.call(event.target);

            //Submit the form
            $.post(obj.options.url, $el.serialize(), function(response)
            {
                if(!response) return false;

                if(!response.errors || response.errors < 1)
                {
                    obj.options.onvalid(response);
                }
                else
                {
                    obj.options.onerror(response);
                    //console.log(obj.options.url); return false;

                    if(response.validation)
                    {
                        $.each(response.validation, function(key, value)
                        {
                            //reset the vars
                            $input, messages, $ul = null;

                            //single Input element
                            $input   = $('#' + key);

                            //Flag the input as error
                            $input.addClass('error');

                            //Create a ul list with all the error messages
                            messages = obj.getMessages(value);

                            //Insert html
                            if(!$input.next('ul').length)
                            {
                                $ul = $('<ul></ul>').addClass('errors');
                                $input.after($ul);
                            }
                            $input.next('ul').html(messages);
                        });
                    }
                }

            }, obj.options.format);

            return false;
        },
        getMessages: function(items)
        {
            var ul = '';
            $.each(items, function(key, value)
            {
                ul += '<li>' + value + '</li>';
            });
            return ul;
        }
    };

    $.plugin('pimForm', pimFormBuild);

})(jQuery);
